/*
 * LocalRollUpMeanT.java
 *
 * Created on January 31, 2005, 2:17 PM
 */

package edu.temple.GUS.MMA.Functions;

import edu.temple.GUS.MMA.DataTypes.*;
import edu.temple.GUS.MMA.Exceptions.MMAFunctionInitException;
import edu.temple.GUS.MMA.util.StatisticalOperator;

/**
 *
 * @author  jeffleon
 */
public class LocalRollUpMeanT {
    
    /** Creates a new instance of LocalRollUpMeanT */
    public LocalRollUpMeanT() {}
    
    // Roll up a time series
    public float execute( MMATimeSeries tSeries ) throws MMAFunctionInitException
    {
        if (tSeries == null)
            throw new MMAFunctionInitException(this.getClass().toString() + " Time series is not initialized.");
        
        // Initialze the t dimension of the timeseries and the noData value
        int t = tSeries.getT();
        float noData = tSeries.getNoData();
        float resultData = 0.0f;
        float temp[] = new float[t];
        
        for ( int i=0; i<t; i++)
            if (tSeries.getElement(i) == noData)
            {
                resultData = noData;
                break;
            }
            else
                 // Store all the t values in temp
                 temp[i] = tSeries.getElement(i);
        
        if (resultData != noData)
            resultData = StatisticalOperator.mean(temp,t);

        return resultData;
    }

    // Roll up a time cube
    public MMAGrid execute( MMATimeCube tCube ) throws MMAFunctionInitException
    {
        if ( tCube == null)
            throw new MMAFunctionInitException(this.getClass().toString() + " Time cube is not initialized.");    

        // Initialze the dimensions of timecube and the noData value
        int x = tCube.getX();
        int y = tCube.getY();
        int t = tCube.getT();
        float noData = tCube.getNoData();

        MMAGrid outputGrid = new MMAGrid(x,y);
        float resultData[][] = new float[y][x];
        float temp[] = new float[t];
        
        for ( int j=0; j <y; j++)
            for ( int i=0; i <x; i++)
            {
                for ( int k=0; k <t; k++)

                    if (tCube.getElement(i,j,k) == noData)
                    {
                        resultData[j][i] = noData;
                        break;
                    }
                    else
                        // Store all the t values in temp
                        temp[k] = tCube.getElement(i,j,k);
                
                if (resultData[j][i] != noData)
                    resultData[j][i] = StatisticalOperator.mean(temp,t);
            }
        
        outputGrid.putData(resultData);
        outputGrid.putNoData(noData);
        
        return outputGrid;
    }

    // Roll up a hyper cube
    public MMASpaceCube execute( MMAHyperCube hCube ) throws MMAFunctionInitException
    {
        if (hCube == null)
            throw new MMAFunctionInitException(this.getClass().toString() + " Hyper cube is not initialized.");    

        // Initialze the dimensions of the hypercube and the noData value
        int x = hCube.getX();
        int y = hCube.getY();
        int z = hCube.getZ();
        int t = hCube.getT();
        float noData = hCube.getNoData(); 

        MMASpaceCube outputCube = new MMASpaceCube(x,y,z);
        float resultData[][][] = new float[z][y][x];
        float temp[] = new float[t];
        
        for ( int k=0; k <z; k++)
            for ( int j=0; j <y; j++)
                for ( int i=0; i <x; i++)
                {
                    for ( int l=0; l <t; l++)

                        if (hCube.getElement(i,j,k,l) == noData)
                        {
                            resultData[l][k][j] = noData;
                            break;
                        }
                        else
                            // Store all the t values in temp
                            temp[l] = hCube.getElement(i,j,k,l);
                
                    if (resultData[k][j][i] != noData)
                        resultData[k][j][i] = StatisticalOperator.mean(temp,t);;
                }
        
        outputCube.putData(resultData);
        outputCube.putNoData(noData);
        return outputCube;
    }
}
